This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.
At the very beginning is an (optional) YAML header surrounded by ---s, the header specifies useful meta data.
Below the header is the first code chunk, this chunk sets global options that apply to every chunk in your file. This is done by calling knitr::opts_chunk$set in this code chunk. Note that these global defaults can be overwritten in individual chunk headers. include = FALSE prevents both codes and results from appearing.
To understand echo = TRUE, message = FALSE and warning = FALSE, read RMarkdown tips and tricks. Energetic Students: read the “Shortening knit time” section and try it in this file
Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Cmd+Shift+Enter.
Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Cmd+Option+I.
When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Cmd+Shift+K to preview the HTML file).
Exercise 8 from ISLR Chapter 2
The following illustrate commands for exploring this exercise using R and various packages for the College data.
Libraries
Try to load the ISLR library
library(ISLR)
If it is not available you will need to install the library from CRAN. Click on Packages in the lower right pane, and then Install. Enter the package name then click on the Install button.
You can also install from the console/command line using install.packages("ISLR").
Ready?
Getting the College data
Next we will need to load the dataset. This is part of the library so we will not need to read it in using read.csv but rather we will use the data function to load it from the library.
data(College)
This loads the dataframe College. Note you can always see the content of any R object by simply typing its name.
College
For information about the variables, read the text or enter
help(College)
The info will appear in the help tab.
To see explore the data, you can use the command View(College).
This will open a new tab, where you may scroll left and right to look at the rows and columns. In the View you should see that the first column is the College/University name. These can be extracted using rownames(College). Let’s print out the first 5
rownames(College)[1:5]
[1] "Abilene Christian University" "Adelphi University" "Adrian College"
[4] "Agnes Scott College" "Alaska Pacific University"
Summary
summary(College)
Private Apps Accept Enroll Top10perc Top25perc
No :212 Min. : 81 Min. : 72 Min. : 35 Min. : 1.00 Min. : 9.0
Yes:565 1st Qu.: 776 1st Qu.: 604 1st Qu.: 242 1st Qu.:15.00 1st Qu.: 41.0
Median : 1558 Median : 1110 Median : 434 Median :23.00 Median : 54.0
Mean : 3002 Mean : 2019 Mean : 780 Mean :27.56 Mean : 55.8
3rd Qu.: 3624 3rd Qu.: 2424 3rd Qu.: 902 3rd Qu.:35.00 3rd Qu.: 69.0
Max. :48094 Max. :26330 Max. :6392 Max. :96.00 Max. :100.0
F.Undergrad P.Undergrad Outstate Room.Board Books Personal
Min. : 139 Min. : 1.0 Min. : 2340 Min. :1780 Min. : 96.0 Min. : 250
1st Qu.: 992 1st Qu.: 95.0 1st Qu.: 7320 1st Qu.:3597 1st Qu.: 470.0 1st Qu.: 850
Median : 1707 Median : 353.0 Median : 9990 Median :4200 Median : 500.0 Median :1200
Mean : 3700 Mean : 855.3 Mean :10441 Mean :4358 Mean : 549.4 Mean :1341
3rd Qu.: 4005 3rd Qu.: 967.0 3rd Qu.:12925 3rd Qu.:5050 3rd Qu.: 600.0 3rd Qu.:1700
Max. :31643 Max. :21836.0 Max. :21700 Max. :8124 Max. :2340.0 Max. :6800
PhD Terminal S.F.Ratio perc.alumni Expend
Min. : 8.00 Min. : 24.0 Min. : 2.50 Min. : 0.00 Min. : 3186
1st Qu.: 62.00 1st Qu.: 71.0 1st Qu.:11.50 1st Qu.:13.00 1st Qu.: 6751
Median : 75.00 Median : 82.0 Median :13.60 Median :21.00 Median : 8377
Mean : 72.66 Mean : 79.7 Mean :14.09 Mean :22.74 Mean : 9660
3rd Qu.: 85.00 3rd Qu.: 92.0 3rd Qu.:16.50 3rd Qu.:31.00 3rd Qu.:10830
Max. :103.00 Max. :100.0 Max. :39.80 Max. :64.00 Max. :56233
Grad.Rate
Min. : 10.00
1st Qu.: 53.00
Median : 65.00
Mean : 65.46
3rd Qu.: 78.00
Max. :118.00
Dimensions of Data
How many observations and variables are in the dataframe?
[1] 777 18
Suppose we want to refer to those numbers in the text. We can extract them using n = 777 and d = 18. Look at the code to see how we extracted them.
Scatter plot matrices
There base R version of scatter plot matrices is obtained using the pairs function to plot all variables versus each other. We can use subsetting of columns of the dataframe to look at the first 5 columns.

We can also look at this using the ggpairs function. Install the library GGally if it is not available (and any dependent libraries) and load it.
library(GGally)
ggpairs(College, columns= c(1,3:5, 2))

The last variable, 2 in this case, refers to our response variable.
Note ggpairs will show its progress in your output and using warning=FALSE or message=FALSE does not suppress it. This answer on this Stackexchange post: provided the trick or progress=F to suppress the progress bar.
gp = ggpairs(College, columns= c(1,3:5, 2))
print(gp, progress=F)

The ggpairs function realizes that the variable Private is categorial and plots side by side histograms. The density plots are also useful for seeing the skewness in the marginal distributions.
What other features do these plots indicate? (Think about assumptions for linear regression)
New variables
Let’s create a new variable Elite by binning the Top10perc variable. We are going to divide universities into two groups based on whether or not the proportion of students coming from the top 10% of their high school classes exceeds 50 %. We will use the library dplyr to illustrate some of the possible transformations and the idea of pipes (%>%), which are quite powerful once you get the hang of them!
For students who are unfamiliar with dplyr, read this intro first.
library(dplyr)
College = College %>%
mutate(Elite = factor(Top10perc > 50)) %>%
mutate(Elite =
recode(Elite, 'TRUE' = "Yes", 'FALSE'="No"))
What is the above doing? Document the code here.
Compare to the base R code:
Elite=rep("No",nrow(College))
Elite[College$Top10perc >50]="Yes"
Elite=as.factor(Elite)
college=data.frame(College ,Elite)
How many Elite universities are there?
summary(College$Elite)
No Yes
699 78
Side by Side Boxplots
Let’s plot the variable Outstate versus Elite using side-by-side boxplots. Using base R we would enter
boxplot(Outstate ~ Elite, data=College,
ylab="Outstate", xlab="Elite")
title("Distribution of Out of State Tuition")

Now for the ggplot version:
library(ggplot2)
my.bp <<-ggplot(data=College, aes(y= Outstate, x=Elite)) # Creates boxplots
my.bp <- my.bp + geom_boxplot() # Adds color
my.bp <- my.bp + ggtitle("Distribution of Out of State Tuition") # Adds a title
my.bp <- my.bp + ylab("Outstate") + xlab("Elite") # Adds lables for axes
my.bp # displays the boxplots

Conditional Plots
Let’s look at the distribution of Out of state tuition versus Elite status for Private versus Public universities using conditional plots
coplot(Outstate ~ Elite | Private, data=College)

ggplot conditional plot
library(ggplot2)
ggplot(College, aes(x = Elite, y = Outstate,
group = Private,
color = Private)) +
geom_point() + facet_grid(.~Private) + ggtitle("Distribution of Out of State Tuition")

Next Steps
Update this document and explore the other variables thinking about the objective of predicting Apps. Document what you discover thinking about models to predict Apps.
Fit a linear model
Use the lm function as described in class to fit a linear model with Apps as the response variable and add one of the predictors in place of XXX below.
For the fitted model, produce diagnostic plots




Discuss whether the model seems appropriate in terms of assumptions.
Updating your work on GitHub
In the upper right you should see a tab labeled Git. Click on that to see a list of files that have been added/changed.
To save changes to github, check the box of any file to add/update. Then click on the Commit link (just above path). In the pop-up window add a Commit message (something meaningful that identifies the changes made). When done, click on Commit to save the changes. Click on the Green Up arrow to push your changes to Github.
Note: Update 8/29/2019 we are still waiting on the github classroom permissions, so you will not be able to push your changes to the class organization site.
LS0tCnRpdGxlOiAiRGVtbyBSU3R1ZGlvIGFuZCBFREEiCmF1dGhvcjogQ2F0aHkgTGVlCm91dHB1dDoKICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgaHRtbF9kb2N1bWVudDogZGVmYXVsdAotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlID0gRkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UpCmBgYAoKVGhpcyBpcyBhbiBbUiBNYXJrZG93bl0oaHR0cDovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbSkgTm90ZWJvb2suIFdoZW4geW91IGV4ZWN1dGUgY29kZSB3aXRoaW4gdGhlIG5vdGVib29rLCB0aGUgcmVzdWx0cyBhcHBlYXIgYmVuZWF0aCB0aGUgY29kZS4KCkF0IHRoZSB2ZXJ5IGJlZ2lubmluZyBpcyBhbiAob3B0aW9uYWwpIFlBTUwgaGVhZGVyIHN1cnJvdW5kZWQgYnkgYC0tLWBzLCB0aGUgaGVhZGVyIHNwZWNpZmllcyB1c2VmdWwgbWV0YSBkYXRhLiAKCkJlbG93IHRoZSBoZWFkZXIgaXMgdGhlIGZpcnN0IGNvZGUgY2h1bmssIHRoaXMgY2h1bmsgc2V0cyBnbG9iYWwgb3B0aW9ucyB0aGF0IGFwcGx5IHRvIGV2ZXJ5IGNodW5rIGluIHlvdXIgZmlsZS4gVGhpcyBpcyBkb25lIGJ5IGNhbGxpbmcgYGtuaXRyOjpvcHRzX2NodW5rJHNldGAgaW4gdGhpcyBjb2RlIGNodW5rLiBOb3RlIHRoYXQgdGhlc2UgZ2xvYmFsIGRlZmF1bHRzIGNhbiBiZSBvdmVyd3JpdHRlbiBpbiBpbmRpdmlkdWFsIGNodW5rIGhlYWRlcnMuIGBpbmNsdWRlID0gRkFMU0VgIHByZXZlbnRzIGJvdGggY29kZXMgYW5kIHJlc3VsdHMgZnJvbSBhcHBlYXJpbmcuCgpUbyB1bmRlcnN0YW5kIGBlY2hvID0gVFJVRWAsIGBtZXNzYWdlID0gRkFMU0VgIGFuZCBgd2FybmluZyA9IEZBTFNFYCwgcmVhZCBbUk1hcmtkb3duIHRpcHMgYW5kIHRyaWNrc10oaHR0cDovL3d3dy5zY2llbmNlLnNtaXRoLmVkdS9+YW1jbmFtYXJhL3NkczI5MS9STWFya2Rvd25UaXBzLmh0bWwpLiBfRW5lcmdldGljIFN0dWRlbnRzOiByZWFkIHRoZSAiU2hvcnRlbmluZyBrbml0IHRpbWUiIHNlY3Rpb24gYW5kIHRyeSBpdCBpbiB0aGlzIGZpbGVfCgpUcnkgZXhlY3V0aW5nIHRoaXMgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpSdW4qIGJ1dHRvbiB3aXRoaW4gdGhlIGNodW5rIG9yIGJ5IHBsYWNpbmcgeW91ciBjdXJzb3IgaW5zaWRlIGl0IGFuZCBwcmVzc2luZyAqQ21kK1NoaWZ0K0VudGVyKi4gCgpBZGQgYSBuZXcgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpJbnNlcnQgQ2h1bmsqIGJ1dHRvbiBvbiB0aGUgdG9vbGJhciBvciBieSBwcmVzc2luZyAqQ21kK09wdGlvbitJKi4KCldoZW4geW91IHNhdmUgdGhlIG5vdGVib29rLCBhbiBIVE1MIGZpbGUgY29udGFpbmluZyB0aGUgY29kZSBhbmQgb3V0cHV0IHdpbGwgYmUgc2F2ZWQgYWxvbmdzaWRlIGl0IChjbGljayB0aGUgKlByZXZpZXcqIGJ1dHRvbiBvciBwcmVzcyAqQ21kK1NoaWZ0K0sqIHRvIHByZXZpZXcgdGhlIEhUTUwgZmlsZSkuCgojIyAgRXhlcmNpc2UgOCBmcm9tIElTTFIgQ2hhcHRlciAyCgpUaGUgZm9sbG93aW5nIGlsbHVzdHJhdGUgY29tbWFuZHMgZm9yIGV4cGxvcmluZyB0aGlzIGV4ZXJjaXNlIHVzaW5nIFIgYW5kIHZhcmlvdXMgcGFja2FnZXMgZm9yIHRoZSBgQ29sbGVnZWAgZGF0YS4KCiMjIyBMaWJyYXJpZXMKClRyeSB0byBsb2FkIHRoZSBgSVNMUmAgbGlicmFyeQpgYGB7cn0KbGlicmFyeShJU0xSKQpgYGAKCklmIGl0IGlzIG5vdCBhdmFpbGFibGUgeW91IHdpbGwgbmVlZCB0byBpbnN0YWxsIHRoZSAgbGlicmFyeSBmcm9tIENSQU4uIENsaWNrIG9uICAqUGFja2FnZXMqIGluIHRoZSBsb3dlciByaWdodCBwYW5lLCBhbmQgIHRoZW4gKkluc3RhbGwqLiAgRW50ZXIgdGhlIHBhY2thZ2UgbmFtZSB0aGVuIGNsaWNrIG9uIHRoZSBJbnN0YWxsIGJ1dHRvbi4KCllvdSBjYW4gYWxzbyBpbnN0YWxsIGZyb20gdGhlIGNvbnNvbGUvY29tbWFuZCBsaW5lIHVzaW5nCmBpbnN0YWxsLnBhY2thZ2VzKCJJU0xSIilgLgoKUmVhZHk/CgojIyMgIEdldHRpbmcgdGhlIENvbGxlZ2UgZGF0YQoKTmV4dCB3ZSB3aWxsIG5lZWQgdG8gbG9hZCB0aGUgZGF0YXNldC4gIFRoaXMgaXMgcGFydCBvZiB0aGUgbGlicmFyeSBzbyB3ZSB3aWxsIG5vdCBuZWVkIHRvIHJlYWQgaXQgaW4gdXNpbmcgYHJlYWQuY3N2YCBidXQgcmF0aGVyIHdlIHdpbGwgdXNlIHRoZSBgZGF0YWAgZnVuY3Rpb24gdG8gbG9hZCBpdCBmcm9tIHRoZSBsaWJyYXJ5LgoKYGBge3IgZGF0YX0KZGF0YShDb2xsZWdlKQpgYGAKClRoaXMgbG9hZHMgdGhlIGRhdGFmcmFtZSBgQ29sbGVnZWAuICBOb3RlIHlvdSBjYW4gYWx3YXlzIHNlZSB0aGUgY29udGVudCBvZiBhbnkgYFJgIG9iamVjdCBieSBzaW1wbHkgdHlwaW5nIGl0cyBuYW1lLgpgYGB7ciwgZXZhbD1GQUxTRX0KQ29sbGVnZQpgYGAKCgpGb3IgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHZhcmlhYmxlcywgcmVhZCB0aGUgdGV4dCBvciBlbnRlcgpgYGB7cn0KaGVscChDb2xsZWdlKQpgYGAKClRoZSBpbmZvIHdpbGwgYXBwZWFyIGluIHRoZSBgaGVscGAgdGFiLgoKVG8gc2VlIGV4cGxvcmUgdGhlIGRhdGEsIHlvdSBjYW4gdXNlIHRoZSBjb21tYW5kIGBWaWV3KENvbGxlZ2UpYC4KClRoaXMgd2lsbCBvcGVuIGEgbmV3IHRhYiwgd2hlcmUgeW91IG1heSBzY3JvbGwgbGVmdCBhbmQgcmlnaHQgdG8gbG9vayBhdCB0aGUgcm93cyBhbmQgY29sdW1ucy4KSW4gdGhlIGBWaWV3YCB5b3Ugc2hvdWxkIHNlZSB0aGF0IHRoZSBmaXJzdCBjb2x1bW4gaXMgdGhlIENvbGxlZ2UvVW5pdmVyc2l0eSBuYW1lLiAgVGhlc2UgY2FuIGJlIGV4dHJhY3RlZCB1c2luZyBgcm93bmFtZXMoQ29sbGVnZSlgLiAgTGV0J3MgcHJpbnQgb3V0IHRoZSBmaXJzdCA1CgpgYGB7cn0Kcm93bmFtZXMoQ29sbGVnZSlbMTo1XQpgYGAKCgoKIyMjIFN1bW1hcnkKCmBgYHtyfQpzdW1tYXJ5KENvbGxlZ2UpCmBgYAoKIyMjIERpbWVuc2lvbnMgb2YgRGF0YQoKSG93IG1hbnkgb2JzZXJ2YXRpb25zIGFuZCB2YXJpYWJsZXMgYXJlIGluIHRoZSBkYXRhZnJhbWU/CgoKYGBge3IgZGltLCBlY2hvPUZBTFNFfQpkID0gZGltKENvbGxlZ2UpCmQKYGBgCgpTdXBwb3NlIHdlIHdhbnQgdG8gcmVmZXIgdG8gdGhvc2UgbnVtYmVycyBpbiB0aGUgdGV4dC4gIFdlIGNhbiBleHRyYWN0IHRoZW0gdXNpbmcgbiA9IGByIGRbMV1gIGFuZCBkID0gYHIgZFsyXWAuCkxvb2sgYXQgdGhlIGNvZGUgdG8gc2VlIGhvdyB3ZSBleHRyYWN0ZWQgdGhlbS4gICAKCiMjIyBTY2F0dGVyIHBsb3QgbWF0cmljZXMKClRoZXJlIGBiYXNlYCBgUmAgdmVyc2lvbiBvZiBzY2F0dGVyIHBsb3QgbWF0cmljZXMgaXMgb2J0YWluZWQgdXNpbmcgdGhlIGBwYWlyc2AgZnVuY3Rpb24gdG8gcGxvdCBhbGwgdmFyaWFibGVzIHZlcnN1cyBlYWNoIG90aGVyLiAgV2UgY2FuIHVzZSBzdWJzZXR0aW5nIG9mIGNvbHVtbnMgb2YgdGhlIGRhdGFmcmFtZSB0bwpsb29rIGF0IHRoZSBmaXJzdCA1IGNvbHVtbnMuICAKCmBgYHtyLCBmaWcud2lkdGg9OH0KcGFpcnMoQ29sbGVnZVssIDE6NV0pCgpgYGAKCldlIGNhbiBhbHNvIGxvb2sgYXQgdGhpcyB1c2luZyB0aGUgYGdncGFpcnNgIGZ1bmN0aW9uLgpJbnN0YWxsIHRoZSBsaWJyYXJ5IGBHR2FsbHlgIGlmIGl0IGlzIG5vdCBhdmFpbGFibGUgKGFuZCBhbnkgZGVwZW5kZW50IGxpYnJhcmllcykgYW5kIGxvYWQgaXQuCgpgYGB7ciBnZ3BhaXJzLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBmaWcud2lkdGg9OH0KbGlicmFyeShHR2FsbHkpCmdncGFpcnMoQ29sbGVnZSwgY29sdW1ucz0gYygxLDM6NSwgMikpCmBgYAoKVGhlIGxhc3QgdmFyaWFibGUsIGAyYCBpbiB0aGlzIGNhc2UsIHJlZmVycyB0byAgb3VyIHJlc3BvbnNlIHZhcmlhYmxlLgoKTm90ZSBgZ2dwYWlyc2Agd2lsbCBzaG93IGl0cyBwcm9ncmVzcyBpbiB5b3VyIG91dHB1dCBhbmQgdXNpbmcgd2FybmluZz1GQUxTRSBvciBtZXNzYWdlPUZBTFNFIGRvZXMgbm90IHN1cHByZXNzIGl0LiBUaGlzIGFuc3dlciBvbiBbdGhpcyBTdGFja2V4Y2hhbmdlIHBvc3Q6XShodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzQxNTc3MzYyL3N1cHByZXNzLWdncGFpcnMtbWVzc2FnZXMtd2hlbi1nZW5lcmF0aW5nLXBsb3QpIHByb3ZpZGVkIHRoZSB0cmljayBvciBgcHJvZ3Jlc3M9RmAgdG8gc3VwcHJlc3MgdGhlIHByb2dyZXNzIGJhci4KCmBgYHtyIGdncGFpcnMtZ29vZCwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0naGlkZScsIGZpZy53aWR0aD04fQpncCA9IGdncGFpcnMoQ29sbGVnZSwgY29sdW1ucz0gYygxLDM6NSwgMikpCnByaW50KGdwLCBwcm9ncmVzcz1GKQpgYGAKClRoZSBgZ2dwYWlyc2AgZnVuY3Rpb24gcmVhbGl6ZXMgdGhhdCB0aGUgdmFyaWFibGUgYFByaXZhdGVgIGlzIGNhdGVnb3JpYWwgYW5kIHBsb3RzIHNpZGUgYnkgc2lkZSBoaXN0b2dyYW1zLiAgVGhlIGRlbnNpdHkgcGxvdHMgYXJlIGFsc28gdXNlZnVsIGZvciBzZWVpbmcgdGhlIHNrZXduZXNzIGluIHRoZSBtYXJnaW5hbCBkaXN0cmlidXRpb25zLgoKV2hhdCBvdGhlciBmZWF0dXJlcyBkbyB0aGVzZSBwbG90cyBpbmRpY2F0ZT8gIF8oVGhpbmsgYWJvdXQgYXNzdW1wdGlvbnMgZm9yIGxpbmVhciByZWdyZXNzaW9uKV8KCgojIyMgTmV3IHZhcmlhYmxlcwoKTGV0J3MgY3JlYXRlIGEgbmV3IHZhcmlhYmxlIGBFbGl0ZWAgYnkgYmlubmluZyB0aGUgYFRvcDEwcGVyY2AgdmFyaWFibGUuIFdlIGFyZSBnb2luZyB0byBkaXZpZGUgdW5pdmVyc2l0aWVzIGludG8gdHdvIGdyb3VwcyBiYXNlZCBvbiB3aGV0aGVyIG9yIG5vdCB0aGUgcHJvcG9ydGlvbiBvZiBzdHVkZW50cyBjb21pbmcgZnJvbSB0aGUgdG9wIDEwJSBvZiB0aGVpciBoaWdoIHNjaG9vbCBjbGFzc2VzIGV4Y2VlZHMgNTAgJS4gIFdlIHdpbGwgdXNlIHRoZSBsaWJyYXJ5IGBkcGx5cmAgdG8gaWxsdXN0cmF0ZSBzb21lIG9mIHRoZSBwb3NzaWJsZSB0cmFuc2Zvcm1hdGlvbnMgYW5kIHRoZSBpZGVhIG9mIHBpcGVzIChgJT4lYCksIHdoaWNoIGFyZSBxdWl0ZSBwb3dlcmZ1bCBvbmNlIHlvdSBnZXQgdGhlIGhhbmcgb2YgdGhlbSEKCkZvciBzdHVkZW50cyB3aG8gYXJlIHVuZmFtaWxpYXIgd2l0aCBgZHBseXJgLCByZWFkIHRoaXMgW2ludHJvXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvZHBseXIvdmlnbmV0dGVzL2RwbHlyLmh0bWwpIGZpcnN0LgoKYGBge3J9CmxpYnJhcnkoZHBseXIpCkNvbGxlZ2UgPSBDb2xsZWdlICU+JSAKICBtdXRhdGUoRWxpdGUgPSBmYWN0b3IoVG9wMTBwZXJjID4gNTApKSAlPiUKICBtdXRhdGUoRWxpdGUgPSAKICAgICAgICAgICByZWNvZGUoRWxpdGUsICdUUlVFJyA9ICJZZXMiLCAnRkFMU0UnPSJObyIpKQogIApgYGAKCgpfV2hhdCBpcyB0aGUgYWJvdmUgZG9pbmc/XyAgICBEb2N1bWVudCB0aGUgY29kZSBoZXJlLgoKQ29tcGFyZSB0byB0aGUgYmFzZSBgUmAgY29kZToKCmBgYHtyLCBldmFsdWF0ZT1GQUxTRX0KRWxpdGU9cmVwKCJObyIsbnJvdyhDb2xsZWdlKSkKRWxpdGVbQ29sbGVnZSRUb3AxMHBlcmMgPjUwXT0iWWVzIgpFbGl0ZT1hcy5mYWN0b3IoRWxpdGUpCmNvbGxlZ2U9ZGF0YS5mcmFtZShDb2xsZWdlICxFbGl0ZSkKYGBgCgpfSG93IG1hbnkgRWxpdGUgdW5pdmVyc2l0aWVzIGFyZSB0aGVyZT9fCgpgYGB7cn0Kc3VtbWFyeShDb2xsZWdlJEVsaXRlKQpgYGAKCiMjIyBTaWRlIGJ5IFNpZGUgQm94cGxvdHMKCkxldCdzIHBsb3QgdGhlIHZhcmlhYmxlIGBPdXRzdGF0ZWAgdmVyc3VzIGBFbGl0ZWAgdXNpbmcgc2lkZS1ieS1zaWRlIGJveHBsb3RzLiAgVXNpbmcgYGJhc2UgUmAgd2Ugd291bGQgZW50ZXIKCmBgYHtyLCBmaWcud2lkdGg9Nn0KYm94cGxvdChPdXRzdGF0ZSB+IEVsaXRlLCBkYXRhPUNvbGxlZ2UsIAogICAgICAgIHlsYWI9Ik91dHN0YXRlIiwgeGxhYj0iRWxpdGUiKQp0aXRsZSgiRGlzdHJpYnV0aW9uIG9mIE91dCBvZiBTdGF0ZSBUdWl0aW9uIikKYGBgCgoKTm93IGZvciB0aGUgYGdncGxvdGAgdmVyc2lvbjoKCgpgYGB7ciwgZmlnLndpZHRoPTZ9CmxpYnJhcnkoZ2dwbG90MikKbXkuYnAgPDwtZ2dwbG90KGRhdGE9Q29sbGVnZSwgYWVzKHk9IE91dHN0YXRlLCB4PUVsaXRlKSkgIyBDcmVhdGVzIGJveHBsb3RzCm15LmJwIDwtIG15LmJwICsgZ2VvbV9ib3hwbG90KCkgIyBBZGRzIGNvbG9yCm15LmJwIDwtIG15LmJwICsgZ2d0aXRsZSgiRGlzdHJpYnV0aW9uIG9mIE91dCBvZiBTdGF0ZSBUdWl0aW9uIikgIyBBZGRzIGEgdGl0bGUKbXkuYnAgPC0gbXkuYnAgKyAgeWxhYigiT3V0c3RhdGUiKSArIHhsYWIoIkVsaXRlIikgIyBBZGRzIGxhYmxlcyBmb3IgYXhlcwpteS5icCAjIGRpc3BsYXlzIHRoZSBib3hwbG90cwpgYGAKCgojIyMgQ29uZGl0aW9uYWwgUGxvdHMKCkxldCdzIGxvb2sgYXQgdGhlIGRpc3RyaWJ1dGlvbiBvZiBPdXQgb2Ygc3RhdGUgdHVpdGlvbiB2ZXJzdXMgRWxpdGUgc3RhdHVzIGZvciBQcml2YXRlIHZlcnN1cyBQdWJsaWMgdW5pdmVyc2l0aWVzIHVzaW5nIF9jb25kaXRpb25hbCBwbG90c18KCmBgYHtyLCBmaWcud2lkdGg9OH0KY29wbG90KE91dHN0YXRlIH4gRWxpdGUgfCBQcml2YXRlLCBkYXRhPUNvbGxlZ2UpCmBgYAoKCiMjICBnZ3Bsb3QgY29uZGl0aW9uYWwgcGxvdAoKYGBge3IsIGZpZy53aWR0aD02LCBlY2hvPVRSVUV9CmxpYnJhcnkoZ2dwbG90MikKZ2dwbG90KENvbGxlZ2UsIGFlcyh4ID0gRWxpdGUsIHkgPSBPdXRzdGF0ZSwgCiAgICAgICAgICAgICAgICAgICAgZ3JvdXAgPSBQcml2YXRlLCAKICAgICAgICAgICAgICAgICAgICBjb2xvciA9IFByaXZhdGUpKSArCiAgIGdlb21fcG9pbnQoKSArIGZhY2V0X2dyaWQoLn5Qcml2YXRlKSArIGdndGl0bGUoIkRpc3RyaWJ1dGlvbiBvZiBPdXQgb2YgU3RhdGUgVHVpdGlvbiIpIAoKYGBgCgoKIyMgTmV4dCBTdGVwcwoKVXBkYXRlIHRoaXMgZG9jdW1lbnQgYW5kIGV4cGxvcmUgdGhlIG90aGVyIHZhcmlhYmxlcyB0aGlua2luZyBhYm91dCB0aGUgb2JqZWN0aXZlIG9mIHByZWRpY3RpbmcgYEFwcHNgLiAgRG9jdW1lbnQgd2hhdCB5b3UgZGlzY292ZXIgdGhpbmtpbmcgYWJvdXQgbW9kZWxzIHRvIHByZWRpY3QgYEFwcHNgLgoKIyMgRml0IGEgbGluZWFyIG1vZGVsCgpVc2UgdGhlIGBsbWAgZnVuY3Rpb24gYXMgZGVzY3JpYmVkIGluIGNsYXNzIHRvIGZpdCBhIGxpbmVhciBtb2RlbCB3aXRoIGBBcHBzYCBhcyB0aGUgcmVzcG9uc2UgdmFyaWFibGUgYW5kIGFkZCAgb25lIG9mIHRoZSBwcmVkaWN0b3JzIGluIHBsYWNlIG9mIGBYWFhgIGJlbG93LiAgIAoKYGBge3J9CiMgYWRkIGxtIGNvZGUgaGVyZQoKbXltb2RlbCA9IGxtKEFwcHMgfiBUb3AxMHBlcmMsIGRhdGE9Q29sbGVnZSkKYGBgCgoKRm9yIHRoZSBmaXR0ZWQgbW9kZWwsIHByb2R1Y2UgZGlhZ25vc3RpYyBwbG90cwoKYGBge3J9CiMgYWRkIGRpYWdub3N0aWMgcGxvdHMgaGVyZQpwbG90KG15bW9kZWwpCmBgYAoKRGlzY3VzcyB3aGV0aGVyIHRoZSBtb2RlbCBzZWVtcyBhcHByb3ByaWF0ZSBpbiB0ZXJtcyBvZiBhc3N1bXB0aW9ucy4KCgojIyBVcGRhdGluZyB5b3VyIHdvcmsgb24gR2l0SHViCgpJbiB0aGUgdXBwZXIgcmlnaHQgeW91IHNob3VsZCBzZWUgYSB0YWIgbGFiZWxlZCBgR2l0YC4gIENsaWNrIG9uIHRoYXQgdG8gc2VlIGEgbGlzdCBvZiBmaWxlcyB0aGF0IGhhdmUgYmVlbiBhZGRlZC9jaGFuZ2VkLgoKVG8gc2F2ZSBjaGFuZ2VzIHRvIGdpdGh1YiwgY2hlY2sgdGhlIGJveCBvZiBhbnkgZmlsZSB0byBhZGQvdXBkYXRlLiAgVGhlbiBjbGljayBvbiB0aGUgYENvbW1pdGAgbGluayAoanVzdCBhYm92ZSBwYXRoKS4gIEluIHRoZSBwb3AtdXAgd2luZG93IGFkZCBhIENvbW1pdCBtZXNzYWdlIChzb21ldGhpbmcgbWVhbmluZ2Z1bCB0aGF0IGlkZW50aWZpZXMgdGhlIGNoYW5nZXMgbWFkZSkuICBXaGVuIGRvbmUsIGNsaWNrIG9uIENvbW1pdCB0byBzYXZlIHRoZSBjaGFuZ2VzLiAgQ2xpY2sgb24gdGhlIEdyZWVuIFVwIGFycm93IHRvIGBwdXNoYCB5b3VyIGNoYW5nZXMgdG8gR2l0aHViLgoKTm90ZTogIFVwZGF0ZSA4LzI5LzIwMTkgIHdlIGFyZSBzdGlsbCB3YWl0aW5nIG9uIHRoZSBnaXRodWIgY2xhc3Nyb29tIHBlcm1pc3Npb25zLCBzbyB5b3Ugd2lsbCBub3QgYmUgYWJsZSB0byBwdXNoIHlvdXIgY2hhbmdlcyB0byB0aGUgY2xhc3Mgb3JnYW5pemF0aW9uIHNpdGUuCg==